package com.zhongwang.mms.module.jiaGongMaterial.service;

import com.zhongwang.mms.common.JsonResult;
import com.zhongwang.mms.gen.entity.*;
import com.zhongwang.mms.module.basic.dao.MMaterialsDao;
import com.zhongwang.mms.module.jiaGongMaterial.dao.MaterialInDao;
import com.zhongwang.mms.module.jiaGongMaterial.dao.MaterialOffsetDao;
import com.zhongwang.mms.module.jiaGongMaterial.dao.MaterialStockDao;
import com.zhongwang.mms.module.jiaGongMaterial.model.JMaterial;
import com.zhongwang.mms.module.jiaGongMaterial.model.JMaterialAllModel;
import com.zhongwang.mms.module.jiaGongMaterial.model.JMaterialDetail;
import com.zhongwang.mms.module.jiaGongMaterial.model.JMaterialInventory;
import com.zhongwang.mms.module.material.dao.ComplexStorageDao;
import com.zhongwang.mms.module.system.log.LogService;
import com.zhongwang.mms.util.BigDecimalUtils;
import com.zhongwang.mms.util.ExportExcelUtils;
import com.zhongwang.mms.util.ShiroUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @Description: 原料库存查询 服务层
 * @Author: China.wsg
 * @Date: 2020/04/01 11:23
 */
@Log4j2
@Service
public class MaterialOffsetService {
    @Autowired
    private LogService logService;
    @Autowired
    private MaterialOffsetDao materialOffsetDao;
    @Autowired
    private MaterialInDao materialInDao;
    @Autowired
    private MMaterialsDao materialsDao;

    @Transactional(rollbackFor = Exception.class)
    public String redDetailTogether(List<Integer> arr) {
        String msg = "";  // 返回提示信息
        String errorReason; // 红冲校验原因
        int errorCount = 0; // 审核失败记录数
        int successCount = 0; // 成功审核记录数
        JMaterialDetail jMaterialDetail;
        JMaterial jMaterial;
        JMaterialInventory jMaterialInventory;
        MMaterials material;

        int count = materialOffsetDao.selectCountDetailByOdaIds(arr);
        int detailOutCount = materialOffsetDao.selectDetailCountByRepCode(arr);
        int detailInCount = materialOffsetDao.selectDetailInCountByRepCode(arr);
        if(count > 1){
            msg = "红冲失败！不是同一调拨单";
            return msg;
        }else if(arr.size() != detailOutCount && arr.size() != detailInCount && count == 1){
            msg = "红冲失败！调拨单明细未全选中";
            return msg;
        }

        for (int i = 0; i < arr.size(); i++) {

            // 取得单据及明细信息
            jMaterialDetail = materialInDao.findMaterialDetailById(arr.get(i));
            jMaterial = materialInDao.selectMaterialById(jMaterialDetail.getOdaOdrId());
            jMaterialInventory = materialInDao.selectByPrimaryKey(jMaterialDetail.getOdaItyId());
            material = materialsDao.selectByPrimaryKey(jMaterialDetail.getOdaMatId());

            // 校验是否满足红冲条件
            errorReason = checkRedValidate(jMaterial, jMaterialDetail, jMaterialInventory, material);
            if (errorReason.length() == 0) {

                //满足冲单条件 执行冲单操作
                redOrderDetailMethod(jMaterial, jMaterialDetail, jMaterialInventory);
                successCount++;
            } else {
                msg = msg + errorReason;
                errorCount++;
                continue;
            }
        }

        logService.saveLog("单据明细批量红冲", "红冲成功：" + successCount + "条, 红冲失败：" + errorCount + "条");

        String returnMsg;
        if (msg.length() > 0) {
            // 有异常数据
            returnMsg = "红冲成功：" + successCount + "条, 红冲失败：" + errorCount + "条。<br>" + msg + "<br> 以上数据红冲失败！";
        } else {
            returnMsg = "红冲成功！";
        }

        return returnMsg;
    }
    /**
     * 校验是否满足红冲条件
     *
     * @param jMaterial       主单
     * @param jMaterialDetail 明细
     * @param jMaterialInventory   出库在库
     * @return
     */
    private String checkRedValidate(JMaterial jMaterial, JMaterialDetail jMaterialDetail, JMaterialInventory jMaterialInventory, MMaterials material) {

        String errorReason = "";
        // 如果已经被红冲，不允许二次红冲(oda_red_flag 红冲标识: 0蓝字 1被红冲)
        // 提示信息：单据号 项目号 原料描述 失败原因
        if (jMaterialDetail.getOdaRedFlag() == 2) {

            errorReason = errorReason + "<br>" + jMaterial.getOdrCode() + "  " + jMaterialDetail.getOdaProCode() + "  " + jMaterialDetail.getMatSpec() + "  已经被红冲";
        }

        // 如果入库单红冲，判断可用库存是否充足(odr_type 入出库类型  1采购入库 2退料入库 4领料出库)
        if (jMaterial.getOdrType() == 1 || jMaterial.getOdrType() == 2) {
            if (jMaterialInventory == null || jMaterialInventory.getItyAvaNum() < jMaterialDetail.getOdaNum()
                    || jMaterialInventory.getItyAvaWeight() < jMaterialDetail.getOdaWeight()) {
                errorReason = errorReason + "<br>" + jMaterial.getOdrCode() + "  " + jMaterialDetail.getOdaProCode() + "  " + jMaterialDetail.getMatSpec() + "  可用在库库存量不足";
            }
        }

        return errorReason;
    }
    /**
     * 满足冲单条件 执行冲单操作
     *
     * @param jMaterial       主单
     * @param jMaterialDetail 明细
     * @param jMaterialInventory   出库在库
     */
    private void redOrderDetailMethod(JMaterial jMaterial, JMaterialDetail jMaterialDetail, JMaterialInventory jMaterialInventory) {
        // 更改明细红字显示状态（oda_red_flag 是否红字显示： 1否 2是；oda_ity_flag 单据明细类型：1：蓝单 2：红单）
        jMaterialDetail.setOdaRedFlag(2);
        jMaterialDetail.setOdaRedDate(new Date());
        jMaterialDetail.setOdaRedUser(ShiroUtils.getUser().getName());
        materialOffsetDao.updateByPrimaryKey(jMaterialDetail);

        // 插入一条新的单据红冲明细记录
        JMaterialDetail redOrderDetail = new JMaterialDetail();
        redOrderDetail.setOdaInType(jMaterialDetail.getOdaInType());
        redOrderDetail.setOdaProCode(jMaterialDetail.getOdaProCode());
        redOrderDetail.setOdaProName(jMaterialDetail.getOdaProName());
        redOrderDetail.setOdaNum(jMaterialDetail.getOdaNum());
        redOrderDetail.setOdaWeight(jMaterialDetail.getOdaWeight());
        redOrderDetail.setOdaBackDate(jMaterialDetail.getOdaBackDate());
        redOrderDetail.setOdaTrackCode(jMaterialDetail.getOdaTrackCode());
        redOrderDetail.setOdaOdrId(jMaterialDetail.getOdaOdrId());
        redOrderDetail.setOdaMatId(jMaterialDetail.getOdaMatId());
        redOrderDetail.setOdaSpec(jMaterialDetail.getOdaSpec());
        redOrderDetail.setOdaBackWeight(jMaterialDetail.getOdaBackWeight());
        redOrderDetail.setOdaPrice(jMaterialDetail.getOdaPrice());
        redOrderDetail.setOdaItyId(jMaterialDetail.getOdaItyId());
        redOrderDetail.setOdaItyFlag(2);
        redOrderDetail.setOdaRedFlag(2);
        redOrderDetail.setSupplier(jMaterialDetail.getSupplier());
        redOrderDetail.setContractNo(jMaterialDetail.getContractNo());
        redOrderDetail.setOdaRedDate(new Date());
        redOrderDetail.setOdaRedUser(ShiroUtils.getUser().getName());
        redOrderDetail.setOdaAmount(jMaterialDetail.getOdaAmount());
        redOrderDetail.setOdaMatSapCode(jMaterialDetail.getOdaMatSapCode());
        materialInDao.insertJMaterialDetail(redOrderDetail);

        // 执行库存在库表数据变更(odr_type 入出库类型  1采购入库 2退料入库 4领料出库)
        if (jMaterial.getOdrType() == 1 || jMaterial.getOdrType() == 2 || jMaterial.getOdrType() == 6) {
            RedInOrderDetail(jMaterialInventory, jMaterialDetail);
//            if(jMaterial.getOdrType() == 6){
//                //回写调拨单状态
//                AllocationOrder allocationOrder = new AllocationOrder();
//                allocationOrder.setOdrCode(jMaterial.getOdrRepId());
//                allocationOrder.setOdrOutStatus(2);
//                allocationOrderDao.updateOutStatusByOdrCode(allocationOrder);
//                //冲主单
//                MOrder mOrder = new MOrder();
//                mOrder.setOdrId(jMaterial.getOdrId());
//                mOrder.setOdrItyFlag(2);
//                orderDao.updateByPrimaryKeySelective(mOrder);
//            }
        }
        else if (jMaterial.getOdrType() == 4 || jMaterial.getOdrType() == 5) {
            RedOutOrderDetail(jMaterialInventory, jMaterialDetail);
//
//            // 如果是串料出库 则更新串料出库状态为 已执行（未出库）状态
//            if (inventory.getItyCeoSourceFlag() != null && inventory.getItyCeoSourceFlag() == 1) {
//                changeOrder = new MChangeOrder();
//                changeOrder.setCeoStatus(3);    // 0删除 1保存 2提交 3执行 4已出库 5归还中 6已归还 7被驳回
//
//                MChangeOrderExample ex = new MChangeOrderExample();
//                MChangeOrderExample.Criteria criteria = ex.createCriteria();
//                criteria.andCeoStatusEqualTo(4);  // 已出库
//                criteria.andCeoNeedItyIdEqualTo(inventory.getItyId());  // 库存在库id
//                changeOrderDao.updateByExampleSelective(changeOrder, ex);
//            }
//            if(order.getOdrType() == 5){
//                //回写调拨单状态
//                AllocationOrder allocationOrder = new AllocationOrder();
//                allocationOrder.setOdrCode(order.getOdrRepId());
//                allocationOrder.setOdrOutStatus(1);
//                allocationOrderDao.updateOutStatusByOdrCode(allocationOrder);
//                //冲主单
//                MOrder mOrder = new MOrder();
//                mOrder.setOdrId(order.getOdrId());
//                mOrder.setOdrItyFlag(2);
//                orderDao.updateByPrimaryKeySelective(mOrder);
//            }
        }
    }
    /**
     * 红冲出库明细库存执行方法
     *
     * @param inventory   现库存记录
     * @param orderDetail 单据明细
     * @return
     */
    public int RedOutOrderDetail(JMaterialInventory inventory, JMaterialDetail orderDetail) {
        // 库存增加
        inventory.setItyNum(BigDecimalUtils.add(inventory.getItyNum(), orderDetail.getOdaNum()));
        inventory.setItyWeight(BigDecimalUtils.add(inventory.getItyWeight(), orderDetail.getOdaWeight()));
        inventory.setItyAvaNum(BigDecimalUtils.add(inventory.getItyAvaNum(), orderDetail.getOdaNum()));
        inventory.setItyAvaWeight(BigDecimalUtils.add(inventory.getItyAvaWeight(), orderDetail.getOdaWeight()));
        return materialInDao.updateByPrimaryKey(inventory);
    }
    /**
     * 红冲入库明细库存执行方法
     *
     * @param jMaterialInventory   现库存记录
     * @param jMaterialDetail 单据明细
     * @return
     */
    public int RedInOrderDetail(JMaterialInventory jMaterialInventory, JMaterialDetail jMaterialDetail) {

        // 库存减少
        jMaterialInventory.setItyNum(BigDecimalUtils.sub(jMaterialInventory.getItyNum(), jMaterialDetail.getOdaNum()));
        jMaterialInventory.setItyWeight(BigDecimalUtils.sub(jMaterialInventory.getItyWeight(), jMaterialDetail.getOdaWeight()));
        jMaterialInventory.setItyAvaNum(BigDecimalUtils.sub(jMaterialInventory.getItyAvaNum(), jMaterialDetail.getOdaNum()));
        jMaterialInventory.setItyAvaWeight(BigDecimalUtils.sub(jMaterialInventory.getItyAvaWeight(), jMaterialDetail.getOdaWeight()));
        return materialInDao.updateByPrimaryKey(jMaterialInventory);
    }

    /**
     * 明细红冲（单条红冲）
     *
     * @param odaId 明细Id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public String redDetailSingle(Integer odaId) {

        String msg = "";  // 返回提示信息
        String errorReason;

        // 取得单据及明细信息
        JMaterialDetail orderDetail = materialInDao.findMaterialDetailById(odaId);
        JMaterial order = materialInDao.selectMaterialById(orderDetail.getOdaOdrId());
        JMaterialInventory inventory = materialInDao.selectByPrimaryKey(orderDetail.getOdaItyId());
        MMaterials material = materialsDao.selectByPrimaryKey(orderDetail.getOdaMatId());

        // 校验是否满足红冲条件
        errorReason = checkRedValidate(order, orderDetail, inventory, material);
        if (errorReason.length() == 0) {

            //满足冲单条件 执行冲单操作
            redOrderDetailMethod(order, orderDetail, inventory);
        } else {
            msg = msg + errorReason + "  ，红冲失败！";
        }

        logService.saveLog("红冲单据明细", "单据编号：" + order.getOdrCode() + "<br> 原料描述：" + (material==null? "":material.getMatNameDesc())
                + "<br> 跟踪号：" + orderDetail.getOdaTrackCode() + "<br> 项目信息" + orderDetail.getOdaProCode() + "  " + orderDetail.getOdaProName()
                + "<br> 重量：" + orderDetail.getOdaWeight());
        return msg.length() > 0 ? msg : "红冲成功！";
    }

}
